package cmd

import (
	"embed"
	"fmt"
	"os"

	"gitee.com/xuender/oils/logs"
	"gitee.com/xuender/reader/app"
	"gitee.com/xuender/reader/pb"
	"github.com/mitchellh/go-homedir"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var (
	cfgFile string
	// WWW 网页.
	WWW *embed.FS
	// Version 版本.
	Version = "v1.0.0"
	// BuildTime 编译日期.
	BuildTime = "0000-00-00"
	// GitCommit 提交.
	GitCommit = "00000000"
	// nolint: gomnd
	config = &pb.Config{
		GitCommit:     GitCommit,
		Version:       Version,
		BuildTime:     BuildTime,
		Paths:         []string{"."},
		Port:          9527,
		MaxFileSize:   3 * 1000 * 1000,
		MaxFolderSize: 100,
		MaxTextLine:   1000,
		Debug:         false,
	}
)

var rootCmd = &cobra.Command{
	Use:   "reader",
	Short: "远程文件阅读器",
	Long: fmt.Sprintf(`远程文件阅读器

reader [目录...]

版本: %s
提交: %s
日期: %s`, Version, GitCommit, BuildTime),
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) > 0 {
			config.Paths = args
		}

		config.Port, _ = cmd.Flags().GetInt32("port")
		config.Debug, _ = cmd.Flags().GetBool("debug")
		config.MaxFileSize, _ = cmd.Flags().GetInt64("max-file-size")
		config.MaxTextLine, _ = cmd.Flags().GetInt64("max-text-line")
		config.MaxFolderSize, _ = cmd.Flags().GetInt64("max-folder-size")

		a := app.InitializeApp(config, WWW)
		defer a.Close()
		a.Run()
	},
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	cobra.CheckErr(rootCmd.Execute())
}

// nolint: gochecknoinits
func init() {
	rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "配置文件 (默认 $HOME/reader.toml)")
	cobra.OnInitialize(initConfig)
	rootCmd.Flags().BoolP("debug", "d", config.Debug, "调试模式")
	rootCmd.Flags().Int64P("max-file-size", "m", config.MaxFileSize, "阅读文件最大尺寸")
	rootCmd.Flags().Int64P("max-folder-size", "f", config.MaxFolderSize, "文件件最大显示条数")
	rootCmd.Flags().Int64P("max-text-line", "l", config.MaxTextLine, "每次加载文件最大行数")
	rootCmd.Flags().Int32P("port", "p", config.Port, "Web端口号")
}

func initConfig() {
	if cfgFile != "" {
		viper.SetConfigFile(cfgFile)
	} else {
		home, err := homedir.Dir()
		cobra.CheckErr(err)

		viper.AddConfigPath(home)
		viper.AddConfigPath(".")
		viper.SetConfigType("toml")
		viper.SetConfigName("reader")
	}

	viper.AutomaticEnv()

	if err := viper.ReadInConfig(); err == nil {
		fmt.Fprintln(os.Stderr, "使用配置文件:", viper.ConfigFileUsed())
		logs.Panic(viper.Unmarshal(config))
	}
}
